// ==================== MQTT客户端配置 ====================
let mqttClient = null;
let isConnected = false;

// 设备状态
let deviceState = {
    temperature: 0,
    tempThresholdMax: 30,
    tempThresholdMin: 10,
    humidity: 0,
    humidThresholdMax: 60,
    humidThresholdMin: 30,
    foodAmount: 0,
    isFoodDispensing: false,
    deviceFd: "",  // 🆕 设备fd（从MQTT接收）
    als: 0,        // 环境光亮度
    lightOn: false // 环境光开关状态
};

// 图表对象
let tempChart = null;
let humidChart = null;
let tempChartData = [];
let humidChartData = [];
let timeCounter = 0;
const MAX_DATA_POINTS = 30; // 最多显示30个数据点

// ==================== 页面加载完成后初始化 ====================
document.addEventListener('DOMContentLoaded', function() {
    initEventListeners();
    initCharts();
    addLog('info', '📱 网页小程序已启动');
});

// ==================== 事件监听器初始化 ====================
function initEventListeners() {
    // MQTT连接按钮
    document.getElementById('connectBtn').addEventListener('click', toggleMqttConnection);
    
    // 页面切换按钮
    document.getElementById('navPage1').addEventListener('click', () => switchPage('page1'));
    document.getElementById('navPage2').addEventListener('click', () => switchPage('page2'));
    document.getElementById('navPage3').addEventListener('click', () => switchPage('page3'));
    
    // 设置按钮
    document.getElementById('tempSettingBtn').addEventListener('click', setTemperatureThreshold);
    document.getElementById('humidSettingBtn').addEventListener('click', setHumidityThreshold);
    document.getElementById('foodSettingBtn').addEventListener('click', setFoodAmount);
    
    // 投喂按钮
    document.getElementById('feedingBtn').addEventListener('click', triggerFeeding);
    
    // 环境光控制按钮
    document.getElementById('lightToggleBtn').addEventListener('click', toggleLight);
    
    // 清空日志按钮
    document.getElementById('clearLogBtn').addEventListener('click', clearLog);
}

// ==================== MQTT连接管理 ====================
function toggleMqttConnection() {
    if (isConnected) {
        disconnectMqtt();
    } else {
        connectMqtt();
    }
}

function connectMqtt() {
    const host = document.getElementById('mqttHost').value;
    const port = parseInt(document.getElementById('mqttPort').value);
    const topic = document.getElementById('mqttTopic').value;
    const subTopic = document.getElementById('mqttSubTopic').value;
    
    addLog('info', `🔌 正在连接MQTT服务器: ${host}:${port}`);
    
    // 生成唯一客户端ID
    const clientId = `webapp_${Math.random().toString(16).substring(2, 10)}_${Date.now()}`;
    addLog('info', `🆔 客户端ID: ${clientId}`);
    
    try {
        // 连接MQTT服务器（WebSocket）
        const url = `ws://${host}:${port}/mqtt`;
        mqttClient = mqtt.connect(url, {
            clientId: clientId,
            clean: true,
            connectTimeout: 4000,
            keepalive: 60,
            reconnectPeriod: 1000
        });
        
        // 连接成功
        mqttClient.on('connect', function() {
            isConnected = true;
            updateConnectionStatus(true);
            addLog('success', '✅ MQTT连接成功！');
            
            // 订阅主题（接收来自网关的数据）
            mqttClient.subscribe(subTopic, function(err) {
                if (!err) {
                    addLog('success', `✅ 已订阅主题: ${subTopic}`);
                } else {
                    addLog('error', `❌ 订阅失败: ${err.message}`);
                }
            });
            
            // 同时订阅发布主题（接收QT和小程序发送的配置）
            mqttClient.subscribe(topic, function(err) {
                if (!err) {
                    addLog('success', `✅ 已订阅主题: ${topic}`);
                } else {
                    addLog('error', `❌ 订阅失败: ${err.message}`);
                }
            });
            
            document.getElementById('connectBtn').textContent = '断开连接';
        });
        
        // 接收消息
        mqttClient.on('message', function(topic, message) {
            handleMqttMessage(topic, message.toString());
        });
        
        // 连接断开
        mqttClient.on('disconnect', function() {
            isConnected = false;
            updateConnectionStatus(false);
            addLog('warning', '⚠️ MQTT连接已断开');
        });
        
        // 连接错误
        mqttClient.on('error', function(error) {
            addLog('error', `❌ MQTT错误: ${error.message}`);
            updateConnectionStatus(false);
        });
        
    } catch (error) {
        addLog('error', `❌ 连接失败: ${error.message}`);
    }
}

function disconnectMqtt() {
    if (mqttClient) {
        mqttClient.end();
        mqttClient = null;
        isConnected = false;
        updateConnectionStatus(false);
        document.getElementById('connectBtn').textContent = '连接';
        addLog('info', '🔌 已断开MQTT连接');
    }
}

// ==================== MQTT消息处理 ====================
function handleMqttMessage(topic, message) {
    addLog('info', `📨 收到消息 [${topic}]: ${message}`);
    
    try {
        const data = JSON.parse(message);
        
        // 根据消息类型处理
        if (data.message_type === 'settings') {
            handleSettingsMessage(data);
        } else if (data.Tem || data.Hum || data.food) {
            // 兼容C语言网关的消息格式
            handleSensorData(data);
        } else {
            addLog('warning', '⚠️ 未知消息格式');
        }
        
    } catch (error) {
        addLog('error', `❌ JSON解析错误: ${error.message}`);
    }
}

// 处理设置消息（来自QT客户端）
function handleSettingsMessage(data) {
    // 更新温度阈值（QT客户端格式）
    if (data.Tem_max !== undefined) {
        deviceState.tempThresholdMax = data.Tem_max;
        deviceState.tempThresholdMin = data.Tem_min;
        document.getElementById('tempRange').textContent = 
            `${deviceState.tempThresholdMin}-${deviceState.tempThresholdMax}°C`;
        document.getElementById('chartTempRange').textContent = 
            `${deviceState.tempThresholdMin}-${deviceState.tempThresholdMax}°C`;
        addLog('success', `✅ 温度阈值已更新: ${deviceState.tempThresholdMin}-${deviceState.tempThresholdMax}°C`);
    }
    
    // 更新湿度阈值（QT客户端格式）
    if (data.Hum_max !== undefined) {
        deviceState.humidThresholdMax = data.Hum_max;
        deviceState.humidThresholdMin = data.Hum_min;
        document.getElementById('humidRange').textContent = 
            `${deviceState.humidThresholdMin}-${deviceState.humidThresholdMax}%`;
        document.getElementById('chartHumidRange').textContent = 
            `${deviceState.humidThresholdMin}-${deviceState.humidThresholdMax}%`;
        addLog('success', `✅ 湿度阈值已更新: ${deviceState.humidThresholdMin}-${deviceState.humidThresholdMax}%`);
    }
    
    // 更新食物（QT客户端格式）
    if (data.food !== undefined) {
        deviceState.foodAmount = data.food;
        document.getElementById('foodValue').textContent = `剩余${deviceState.foodAmount}`;
        addLog('success', `✅ 食物数量已更新: ${deviceState.foodAmount}`);
    }
}

// 处理传感器数据（来自C语言网关）
function handleSensorData(data) {
    let hasData = false;
    
    // 提取并保存fd值（接收int或string，统一保存为string）
    if (data.fd !== undefined) {
        deviceState.deviceFd = String(data.fd);  // int或string都转为string
        addLog('info', `🆔 设备fd: ${data.fd}`);
        hasData = true;
    }
    
    // 温度数据（C语言网关格式：Tem，值为字符串）
    if (data.Tem !== undefined) {
        const temp = parseFloat(data.Tem);
        deviceState.temperature = temp;
        updateTemperatureDisplay(temp);
        hasData = true;
    }
    
    // 湿度数据（C语言网关格式：Hum，值为字符串）
    if (data.Hum !== undefined) {
        const humid = parseFloat(data.Hum);
        deviceState.humidity = humid;
        updateHumidityDisplay(humid);
        hasData = true;
    }
    
    // 食物数据（C语言网关格式：food，值为字符串）
    if (data.food !== undefined) {
        const food = parseInt(data.food);
        deviceState.foodAmount = food;
        document.getElementById('foodValue').textContent = `剩余${food}`;
        addLog('info', `🍖 食物数据更新: ${food}`);
        hasData = true;
    }
    
    // 环境光数据（C语言网关格式：ALS，值为字符串）
    if (data.ALS !== undefined) {
        const als = parseInt(data.ALS);
        deviceState.als = als;
        document.getElementById('alsValue').textContent = als;
        addLog('info', `💡 环境光数据: ${als}`);
        hasData = true;
    }
    
    if (!hasData) {
        addLog('warning', '⚠️ 消息不包含可识别的数据字段');
    }
}

// ==================== 页面切换 ====================
function switchPage(pageId) {
    // 隐藏所有页面
    document.querySelectorAll('.page-content').forEach(page => {
        page.style.display = 'none';
    });
    
    // 移除所有按钮的active类
    document.querySelectorAll('.nav-btn').forEach(btn => {
        btn.classList.remove('active');
    });
    
    // 显示选中页面
    document.getElementById(pageId).style.display = pageId === 'page1' ? 'grid' : 'block';
    
    // 激活对应按钮
    document.getElementById('nav' + pageId.charAt(0).toUpperCase() + pageId.slice(1)).classList.add('active');
    
    addLog('info', `📄 切换到页面: ${pageId}`);
}

// ==================== 图表初始化 ====================
function initCharts() {
    // 初始化温度图表
    const tempCtx = document.getElementById('tempChart').getContext('2d');
    tempChart = new Chart(tempCtx, {
        type: 'line',
        data: {
            labels: [],
            datasets: [{
                label: '温度 (°C)',
                data: [],
                borderColor: '#667eea',
                backgroundColor: 'rgba(102, 126, 234, 0.1)',
                tension: 0.4,
                fill: true
            }, {
                label: '最高阈值',
                data: [],
                borderColor: '#f44336',
                borderDash: [5, 5],
                borderWidth: 2,
                pointRadius: 0,
                fill: false
            }, {
                label: '最低阈值',
                data: [],
                borderColor: '#2196F3',
                borderDash: [5, 5],
                borderWidth: 2,
                pointRadius: 0,
                fill: false
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: {
                    display: true,
                    position: 'top'
                },
                title: {
                    display: true,
                    text: '温度变化曲线'
                }
            },
            scales: {
                x: {
                    title: {
                        display: true,
                        text: '时间点'
                    }
                },
                y: {
                    title: {
                        display: true,
                        text: '温度 (°C)'
                    },
                    min: 0,
                    max: 50
                }
            }
        }
    });
    
    // 初始化湿度图表
    const humidCtx = document.getElementById('humidChart').getContext('2d');
    humidChart = new Chart(humidCtx, {
        type: 'line',
        data: {
            labels: [],
            datasets: [{
                label: '湿度 (%)',
                data: [],
                borderColor: '#4CAF50',
                backgroundColor: 'rgba(76, 175, 80, 0.1)',
                tension: 0.4,
                fill: true
            }, {
                label: '最高阈值',
                data: [],
                borderColor: '#f44336',
                borderDash: [5, 5],
                borderWidth: 2,
                pointRadius: 0,
                fill: false
            }, {
                label: '最低阈值',
                data: [],
                borderColor: '#2196F3',
                borderDash: [5, 5],
                borderWidth: 2,
                pointRadius: 0,
                fill: false
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: {
                    display: true,
                    position: 'top'
                },
                title: {
                    display: true,
                    text: '湿度变化曲线'
                }
            },
            scales: {
                x: {
                    title: {
                        display: true,
                        text: '时间点'
                    }
                },
                y: {
                    title: {
                        display: true,
                        text: '湿度 (%)'
                    },
                    min: 0,
                    max: 100
                }
            }
        }
    });
}

// ==================== UI更新函数 ====================
function updateTemperatureDisplay(temp) {
    const tempValue = document.getElementById('tempValue');
    const tempStatus = document.getElementById('tempStatus');
    
    tempValue.textContent = `${temp.toFixed(1)}°C`;
    
    // 判断温度状态
    if (temp >= deviceState.tempThresholdMax) {
        tempStatus.textContent = '温度过高';
        tempStatus.className = 'metric-status high';
    } else if (temp <= deviceState.tempThresholdMin) {
        tempStatus.textContent = '温度过低';
        tempStatus.className = 'metric-status low';
    } else {
        tempStatus.textContent = '温度正常';
        tempStatus.className = 'metric-status normal';
    }
    
    // 更新图表页面的温度显示
    document.getElementById('chartTempValue').textContent = `${temp.toFixed(1)}°C`;
    
    // 添加数据到图表
    addTemperatureToChart(temp);
    
    addLog('info', `🌡️ 温度更新: ${temp.toFixed(1)}°C`);
}

function updateHumidityDisplay(humid) {
    const humidValue = document.getElementById('humidValue');
    const humidStatus = document.getElementById('humidStatus');
    
    humidValue.textContent = `${humid.toFixed(1)}%`;
    
    // 判断湿度状态
    if (humid >= deviceState.humidThresholdMax) {
        humidStatus.textContent = '湿度过高';
        humidStatus.className = 'metric-status high';
    } else if (humid <= deviceState.humidThresholdMin) {
        humidStatus.textContent = '湿度过低';
        humidStatus.className = 'metric-status low';
    } else {
        humidStatus.textContent = '湿度正常';
        humidStatus.className = 'metric-status normal';
    }
    
    // 更新图表页面的湿度显示
    document.getElementById('chartHumidValue').textContent = `${humid.toFixed(1)}%`;
    
    // 添加数据到图表
    addHumidityToChart(humid);
    
    addLog('info', `💧 湿度更新: ${humid.toFixed(1)}%`);
}

function updateConnectionStatus(connected) {
    const statusDot = document.getElementById('statusDot');
    const statusText = document.getElementById('statusText');
    
    if (connected) {
        statusDot.className = 'status-dot connected';
        statusText.textContent = '已连接';
    } else {
        statusDot.className = 'status-dot disconnected';
        statusText.textContent = '未连接';
    }
}

// ==================== 图表数据更新 ====================
function addTemperatureToChart(temp) {
    // 添加数据点
    tempChartData.push(temp);
    
    // 保持最多30个数据点
    if (tempChartData.length > MAX_DATA_POINTS) {
        tempChartData.shift();
    }
    
    // 更新图表
    const labels = tempChartData.map((_, index) => index + 1);
    tempChart.data.labels = labels;
    tempChart.data.datasets[0].data = tempChartData;
    
    // 更新阈值线
    const maxThresholdData = new Array(tempChartData.length).fill(deviceState.tempThresholdMax);
    const minThresholdData = new Array(tempChartData.length).fill(deviceState.tempThresholdMin);
    tempChart.data.datasets[1].data = maxThresholdData;
    tempChart.data.datasets[2].data = minThresholdData;
    
    tempChart.update('none'); // 'none'模式不使用动画，性能更好
}

function addHumidityToChart(humid) {
    // 添加数据点
    humidChartData.push(humid);
    
    // 保持最多30个数据点
    if (humidChartData.length > MAX_DATA_POINTS) {
        humidChartData.shift();
    }
    
    // 更新图表
    const labels = humidChartData.map((_, index) => index + 1);
    humidChart.data.labels = labels;
    humidChart.data.datasets[0].data = humidChartData;
    
    // 更新阈值线
    const maxThresholdData = new Array(humidChartData.length).fill(deviceState.humidThresholdMax);
    const minThresholdData = new Array(humidChartData.length).fill(deviceState.humidThresholdMin);
    humidChart.data.datasets[1].data = maxThresholdData;
    humidChart.data.datasets[2].data = minThresholdData;
    
    humidChart.update('none');
}

// ==================== 设置阈值 ====================
function setTemperatureThreshold() {
    const maxTemp = prompt('请输入温度最高阈值(°C):', deviceState.tempThresholdMax);
    if (maxTemp === null) return;
    
    const minTemp = prompt('请输入温度最低阈值(°C):', deviceState.tempThresholdMin);
    if (minTemp === null) return;
    
    const max = parseInt(maxTemp);
    const min = parseInt(minTemp);
    
    if (min >= max) {
        alert('最低阈值不能大于等于最高阈值！');
        return;
    }
    
    deviceState.tempThresholdMax = max;
    deviceState.tempThresholdMin = min;
    
    document.getElementById('tempRange').textContent = `${min}-${max}°C`;
    document.getElementById('chartTempRange').textContent = `${min}-${max}°C`;
    
    // 更新图表阈值线
    if (tempChart && tempChartData.length > 0) {
        const maxThresholdData = new Array(tempChartData.length).fill(max);
        const minThresholdData = new Array(tempChartData.length).fill(min);
        tempChart.data.datasets[1].data = maxThresholdData;
        tempChart.data.datasets[2].data = minThresholdData;
        tempChart.update();
    }
    
    // 发送设置到MQTT
    sendAllSettings();
    
    addLog('success', `✅ 温度阈值已设置: ${min}-${max}°C`);
}

function setHumidityThreshold() {
    const maxHumid = prompt('请输入湿度最高阈值(%):', deviceState.humidThresholdMax);
    if (maxHumid === null) return;
    
    const minHumid = prompt('请输入湿度最低阈值(%):', deviceState.humidThresholdMin);
    if (minHumid === null) return;
    
    const max = parseInt(maxHumid);
    const min = parseInt(minHumid);
    
    if (min >= max) {
        alert('最低阈值不能大于等于最高阈值！');
        return;
    }
    
    deviceState.humidThresholdMax = max;
    deviceState.humidThresholdMin = min;
    
    document.getElementById('humidRange').textContent = `${min}-${max}%`;
    document.getElementById('chartHumidRange').textContent = `${min}-${max}%`;
    
    // 更新图表阈值线
    if (humidChart && humidChartData.length > 0) {
        const maxThresholdData = new Array(humidChartData.length).fill(max);
        const minThresholdData = new Array(humidChartData.length).fill(min);
        humidChart.data.datasets[1].data = maxThresholdData;
        humidChart.data.datasets[2].data = minThresholdData;
        humidChart.update();
    }
    
    // 发送设置到MQTT
    sendAllSettings();
    
    addLog('success', `✅ 湿度阈值已设置: ${min}-${max}%`);
}

function setFoodAmount() {
    const newAmount = prompt('请输入食物数量:', deviceState.foodAmount);
    if (newAmount === null) return;
    
    const amount = parseInt(newAmount);
    deviceState.foodAmount = amount;
    
    document.getElementById('foodValue').textContent = `剩余${amount}`;
    
    // 发送设置到MQTT
    sendAllSettings();
    
    addLog('success', `✅ 食物数量已设置: ${amount}`);
}

// ==================== MQTT消息发送 ====================
function sendAllSettings() {
    if (!isConnected || !mqttClient) {
        addLog('error', '❌ MQTT未连接，无法发送设置');
        return;
    }
    
    const topic = document.getElementById('mqttTopic').value;
    
    const message = {
        fd: parseInt(deviceState.deviceFd) || 0,            // 设备fd转为int
        Tem_max: deviceState.tempThresholdMax,              // 数字类型
        Tem_min: deviceState.tempThresholdMin,              // 数字类型
        Hum_max: deviceState.humidThresholdMax,             // 数字类型
        Hum_min: deviceState.humidThresholdMin,             // 数字类型
        food: deviceState.foodAmount                        // 数字类型
    };
    
    const payload = JSON.stringify(message);
    
    mqttClient.publish(topic, payload, function(err) {
        if (err) {
            addLog('error', `❌ 发送失败: ${err.message}`);
        } else {
            addLog('success', `✅ 设置已发送到主题: ${topic}`);
            addLog('info', `📦 消息内容: ${payload}`);
        }
    });
}

// 投喂触发
function triggerFeeding() {
    if (!isConnected || !mqttClient) {
        addLog('error', '❌ MQTT未连接，无法发送投喂命令');
        alert('请先连接MQTT服务器！');
        return;
    }
    
    const topic = document.getElementById('mqttTopic').value;
    
    const message = {
        fd: parseInt(deviceState.deviceFd) || 0,  // 设备fd转为int
        feed: "1"                  // 投喂命令（字符串格式，与QT客户端一致）
    };
    
    const payload = JSON.stringify(message);
    
    mqttClient.publish(topic, payload, function(err) {
        if (err) {
            addLog('error', `❌ 投喂命令发送失败: ${err.message}`);
        } else {
            addLog('success', `✅ 投喂命令已发送`);
            addLog('info', `📦 投喂消息: ${payload}`);
        }
    });
}

// 切换环境光
function toggleLight() {
    if (!isConnected || !mqttClient) {
        addLog('error', '❌ MQTT未连接，无法发送环境光控制命令');
        alert('请先连接MQTT服务器！');
        return;
    }
    
    const newState = !deviceState.lightOn;
    deviceState.lightOn = newState;
    
    const topic = document.getElementById('mqttTopic').value;
    
    const message = {
        fd: parseInt(deviceState.deviceFd) || 0,  // 设备fd转为int
        led: newState ? "1" : "0"  // 开是1，关是0（字符串格式，与QT统一）
    };
    
    const payload = JSON.stringify(message);
    
    mqttClient.publish(topic, payload, function(err) {
        if (err) {
            addLog('error', `❌ 环境光控制失败: ${err.message}`);
            deviceState.lightOn = !newState; // 恢复状态
        } else {
            // 更新UI
            const lightIcon = document.getElementById('lightIcon');
            const lightText = document.getElementById('lightText');
            const lightBtn = document.getElementById('lightToggleBtn');
            
            if (newState) {
                lightIcon.textContent = '💡';
                lightText.textContent = '关闭环境光';
                lightBtn.style.backgroundColor = '#ffc107';
            } else {
                lightIcon.textContent = '🌙';
                lightText.textContent = '开启环境光';
                lightBtn.style.backgroundColor = '#6c757d';
            }
            
            addLog('success', `✅ 环境光已${newState ? '开启' : '关闭'}`);
            addLog('info', `📦 环境光控制消息: ${payload}`);
        }
    });
}

// ==================== 日志管理 ====================
function addLog(type, message) {
    const logContent = document.getElementById('logContent');
    const timestamp = new Date().toLocaleTimeString('zh-CN');
    const logEntry = document.createElement('div');
    logEntry.className = `log-entry ${type}`;
    logEntry.textContent = `[${timestamp}] ${message}`;
    
    logContent.appendChild(logEntry);
    logContent.scrollTop = logContent.scrollHeight;
    
    // 限制日志条数（最多100条）
    const entries = logContent.getElementsByClassName('log-entry');
    if (entries.length > 100) {
        logContent.removeChild(entries[0]);
    }
}

function clearLog() {
    document.getElementById('logContent').innerHTML = '';
    addLog('info', '📋 日志已清空');
}

// ==================== 工具函数 ====================
// 格式化时间
function formatTime(date) {
    return date.toLocaleTimeString('zh-CN', { 
        hour12: false, 
        hour: '2-digit', 
        minute: '2-digit', 
        second: '2-digit' 
    });
}

// 页面卸载时清理
window.addEventListener('beforeunload', function() {
    if (mqttClient) {
        mqttClient.end();
    }
});

